// QuickView.cpp : implementation file
//

#include "stdafx.h"
#include "Redirect.h"
#include "WinPlace.h"
#include "QuickVview.h"

#include "ToolBar.h"


//#include "LppDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CQuickView

IMPLEMENT_DYNCREATE(CQuickView, CRichEditView)

CQuickView::CQuickView()
{
	m_nMaxLine = theApp.m_nMaxLine;
	m_bPastToSize = theApp.m_bPastToSize;
	m_CharHeight = 0;
    m_nEditPos = 0;
    m_nStartChar = 0;
    m_nStopChar = 0;
	m_bReadOnly = FALSE;
}

CQuickView::~CQuickView()
{
    if (m_font.m_hObject != NULL)
		m_font.DeleteObject();
}

BEGIN_MESSAGE_MAP(CQuickView, CRichEditView)
	//{{AFX_MSG_MAP(CQuickView)
	ON_WM_CREATE()
	ON_COMMAND(ID_EDIT_CLEAR_ALL, OnEditClearAll)
	ON_UPDATE_COMMAND_UI(ID_EDIT_CLEAR_ALL, OnUpdateEditClearAll)
	ON_COMMAND(ID_EDIT_WRAP, OnEditWrap)
	ON_UPDATE_COMMAND_UI(ID_EDIT_WRAP, OnUpdateEditWrap)
	ON_COMMAND(ID_LINE_PER_PAGE, OnLinePerPage)
	ON_WM_SIZE()
	ON_WM_DESTROY()
	ON_WM_CHAR()
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CRichEditView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CRichEditView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CRichEditView::OnFilePrintPreview)
END_MESSAGE_MAP()

int CQuickView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CRichEditView::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// Use 8pt Courier (monospace)
	LOGFONT logfont;
	memset(&logfont, 0, sizeof(logfont));

	CWindowDC dc(NULL);

	
	
	WrapChanged();

	return 0;
}

void CQuickView::SetReadOnly(BOOL bReadOnly)
{
  m_bReadOnly = bReadOnly;
  GetRichEditCtrl().SetReadOnly(m_bReadOnly);
}

/////////////////////////////////////////////////////////////////////////////
// CQuickView diagnostics

#ifdef _DEBUG
void CQuickView::AssertValid() const
{
	CRichEditView::AssertValid();
}

void CQuickView::Dump(CDumpContext& dc) const
{
	CRichEditView::Dump(dc);
}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CQuickView operations

BOOL CQuickView::IsEmpty() 
{
	CRichEditCtrl &EditCtrl = GetRichEditCtrl();
	return EditCtrl.GetLineCount() <= 1 && EditCtrl.LineLength() == 0;
}

void CQuickView::DeleteExtraLines(LPCTSTR lpszStr)
{
	// if linecount > m_nMaxLine, delete the first lines
	if (m_nMaxLine == 0) return;
	CRichEditCtrl &EditCtrl = GetRichEditCtrl();

	int nNewLine = 0;
	if (lpszStr != NULL)
	{
		LPCTSTR p = lpszStr;
		while (*p && *p == '\n') nNewLine++;
	}
	int nLineCount = EditCtrl.GetLineCount() + nNewLine;
	if (nLineCount > m_nMaxLine)
	{
		SetRedraw(FALSE);
		int nLastChar = EditCtrl.LineIndex(nLineCount - m_nMaxLine);
		EditCtrl.SetSel(0, nLastChar);
		EditCtrl.Clear();
		SetRedraw(TRUE);
		Invalidate();
	}
}

void CQuickView::Append(LPCTSTR lpszStr)
{
	CString strText = lpszStr;
	//strText.Replace("\n\r", "\r\n");
	//strText.Replace("\r\r", "\r\n");
	//strText.Replace("\n\n", "\r\n");

	DeleteExtraLines();
	CRichEditCtrl &EditCtrl = GetRichEditCtrl();
    EditCtrl.SetSel(-1, -1);				        // end of edit text
    EditCtrl.ReplaceSel(strText);					// append string..
    EditCtrl.SendMessage(EM_SCROLLCARET);	        // ..and show caret
    EditCtrl.GetSel(m_nStartChar, m_nStopChar);     // save position
}

void CQuickView::WriteTTY(LPCTSTR lpszStr)
{
	Append(lpszStr);
}

BOOL CQuickView::OpenFile(CFile& File, LPCSTR lpszPathName)
{
	BOOL bOpen = FALSE;
	TRY
	{
		bOpen = File.Open(lpszPathName, CFile::modeCreate|CFile::modeWrite|CFile::shareDenyWrite);
	}
	CATCH_ALL(e)
	{
	}
	END_CATCH_ALL

	if (!bOpen)
	{
		MessageBox("Failed to open file.", AfxGetAppName(), MB_OK|MB_ICONEXCLAMATION);
		MessageBeep(MB_ICONEXCLAMATION);
	}
	return bOpen;
}

/////////////////////////////////////////////////////////////////////////////
// CQuickView message handlers

void CQuickView::OnEditWrap() 
{
	m_nWordWrap = (m_nWordWrap == WrapNone) ? WrapToWindow: WrapNone;
	WrapChanged();
}

void CQuickView::OnUpdateEditWrap(CCmdUI* pCmdUI) 
{
	pCmdUI->SetCheck(m_nWordWrap != WrapNone);
}

void CQuickView::OnEditClearAll() 
{
	CRichEditCtrl &EditCtrl = GetRichEditCtrl();
	GetRichEditCtrl().SetReadOnly(FALSE);
	EditCtrl.SetSel(0, -1);		//  select whole buffer
	EditCtrl.Clear();			// ..then delete
	GetRichEditCtrl().SetReadOnly(m_bReadOnly);
}

void CQuickView::OnUpdateEditClearAll(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(!IsEmpty());
}

void CQuickView::OnLinePerPage() 
{
	CLinePerPageDlg dlg;
	dlg.m_nMaxLine = m_nMaxLine;
	dlg.m_bPastToSize = m_bPastToSize;
	if (dlg.DoModal() == IDOK)
	{
		m_nMaxLine = dlg.m_nMaxLine;
		m_bPastToSize = dlg.m_bPastToSize;

		if (m_bPastToSize)
		{
			ASSERT(m_CharHeight != 0);
			CRect rect; GetClientRect(&rect);
			m_nMaxLine = rect.Height() / m_CharHeight - 1;
			if (m_nMaxLine < 0) m_nMaxLine = 1;
		}

		if (m_nMaxLine != 0)
		{
			DeleteExtraLines();
			Invalidate(TRUE);
		}
	}
}

void CQuickView::OnSize(UINT nType, int cx, int cy) 
{
	CRichEditView::OnSize(nType, cx, cy);
	if (cy && m_CharHeight != 0 && m_bPastToSize)
	{
		m_nMaxLine = cy / m_CharHeight - 1;
		if (m_nMaxLine < 0) m_nMaxLine = 1;
		DeleteExtraLines();
	}
}

void CQuickView::OnDestroy() 
{
	// save to application and close
	CRichEditView::OnDestroy();
}

void CQuickView::DeleteCommand()
{
    // delete input for echo
    long nStartChar, nStopChar;
    CRichEditCtrl &EditCtrl = GetRichEditCtrl();
    EditCtrl.GetSel(nStartChar, nStopChar);
    EditCtrl.SetSel(m_nStartChar, nStopChar);
    EditCtrl.Clear();
}

void CQuickView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	if (!m_bReadOnly && theApp.IsChildRunning())
	{
        if (theApp.m_bUseBuffer && nChar != 0x03)	// Ctrl-C
        {
			switch (nChar)
			{
				case VK_RETURN:
                {
					switch (theApp.m_CRLF)
					{
						case 0:	// CR
							m_EditBuffer[m_nEditPos] = '\r';
							if (m_nEditPos < BUFFER_SIZE-1) m_nEditPos++;
							break;
						case 1:	// LF
							m_EditBuffer[m_nEditPos] = '\n';
							if (m_nEditPos < BUFFER_SIZE-1) m_nEditPos++;
							break;
						case 2:	// CR+LF
							m_EditBuffer[m_nEditPos] = '\r';
							if (m_nEditPos < BUFFER_SIZE-1) m_nEditPos++;
							m_EditBuffer[m_nEditPos] = '\n';
							if (m_nEditPos < BUFFER_SIZE-1) m_nEditPos++;
							break;
					}
					m_EditBuffer[m_nEditPos] = '\0';
					if (m_nEditPos < BUFFER_SIZE-1) m_nEditPos++;
		            
                    
                    
                    m_nEditPos = 0;

					// don't send CR to the View in command mode (received back in echo)
                    

                    break;
                }
				case VK_BACK:
					if (m_nEditPos > 0)
						m_nEditPos--;
					break;
				default:
                    m_EditBuffer[m_nEditPos] = nChar;
					if (m_nEditPos < BUFFER_SIZE-1) m_nEditPos++;
			}
        }
        else
        {
			int nEditPos = 0;
			CHAR EditBuffer[3];
		    if (nChar == VK_RETURN)
            {
				switch (theApp.m_CRLF)
				{
					case 0:	// CR
						EditBuffer[nEditPos++] = '\r';
						break;
					case 1:	// LF
						EditBuffer[nEditPos++] = '\n';
						break;
					case 2:	// CR+LF
						EditBuffer[nEditPos++] = '\r';
						EditBuffer[nEditPos++] = '\n';
						break;
				}
            }
			else
				EditBuffer[nEditPos++] = nChar;
            EditBuffer[nEditPos++] = '\0';

            if (theApp.m_bOemToAnsi) ::CharToOem(EditBuffer, EditBuffer);
            theApp.AddCommand(STDIO_WRITE, EditBuffer);

            // don't send CR to the View in command mode (received back in echo)
			if (nChar == VK_RETURN && theApp.m_bCommand) return;
        }

		// don't send the character to the view in half duplex (received back in echo)
        if (theApp.m_HalfDuplex) return;
    }
	CRichEditView::OnChar(nChar, nRepCnt, nFlags);
}



